/**
 * 
 */
package com.google.gwt.indexeddb.client;

import com.google.gwt.core.client.JavaScriptException;
import com.google.gwt.core.client.JavaScriptObject;

/**
 * The IDBIndex interface of the IndexedDB API provides asynchronous access to
 * an index in a database.
 * 
 * @author Chan Le <gwt /at/ chanvn.com>
 * @see <a href="http://www.w3.org/TR/IndexedDB/#index">W3C IndexedDB Index</a>
 */
public class IDBIndex extends JavaScriptObject {

  protected IDBIndex() {
  }

  /**
   * Returns an IDBRequest object, and, in a separate thread, finds either the
   * value in the referenced object store that corresponds to the given key, or
   * the first corresponding value, if key is a key range. If a value is
   * successfully found, then a structured clone of it is created and set as the
   * result of the request object.
   * 
   * @param key key or key range that identifies the record to be retrieved
   * @return A request object on which subsequent events related to this
   *         operation are fired.
   * @throws IDBDatabaseException
   * @see <a href="http://www.w3.org/TR/IndexedDB/#widl-IDBIndex-get">W3C
   *      IDBIndex-get</a>
   */
  public final IDBRequest get(Object key) throws IDBDatabaseException {
    try {
      return get0(key);
    } catch (JavaScriptException e) {
      throw new IDBDatabaseException(e.getName(), e);
    }
  }

  private final native IDBRequest get0(Object key) /*-{
		return this.get(key);
  }-*/;

  /**
   * Returns a IDBRequest object, and, in a separate thread, finds either the
   * value from this index that corresponds to the given key, or the first
   * corresponding value, if key is a key range. If the value is successfully
   * found, then the result of the request object is set to the value retrieved.
   * 
   * @param key The key that identifies the record to be retrieved
   * @return A request object on which subsequent events related to this
   *         operation are fired.
   * @throws IDBDatabaseException
   * @see <a href="http://www.w3.org/TR/IndexedDB/#widl-IDBIndex-getKey">W3C
   *      IDBIndex-getKey</a>
   */
  public final IDBRequest getKey(Object key) throws IDBDatabaseException {
    try {
      return getKey0(key);
    } catch (JavaScriptException e) {
      throw new IDBDatabaseException(e.getName(), e);
    }
  }

  private final native IDBRequest getKey0(Object key) /*-{
		return this.getKey(key);
  }-*/;

  /**
   * @return The key path of this index. If null, this index is not
   *         auto-populated.
   * @see <a href="http://www.w3.org/TR/IndexedDB/#widl-IDBIndex-keyPath">W3C
   *      IDBIndex-keyPath</a>
   */
  public final native String getKeyPath() /*-{
		return this.keyPath;
  }-*/;

  /**
   * @return The name of this index
   * @see <a href="http://www.w3.org/TR/IndexedDB/#widl-IDBIndex-name">W3C
   *      IDBIndex-name</a>
   */
  public final native String getName() /*-{
		return this.name;
  }-*/;

  /**
   * @return The name of the object store referenced by this index.
   * @see <a
   *      href="http://www.w3.org/TR/IndexedDB/#widl-IDBIndex-objectStore">W3C
   *      IDBIndex-objectStore </a>
   */
  public final native String getStoreName() /*-{
		return this.storeName;
  }-*/;

  /**
   * @return If true, this index does not allow duplicate values for a key.
   * @see <a href="http://www.w3.org/TR/IndexedDB/#widl-IDBIndex-unique">W3C
   *      IDBIndex-unique</a>
   */
  public final native boolean getUnique() /*-{
		return this.unique;
  }-*/;

  /**
   * Returns an IDBRequest object, and, in a separate thread, creates a cursor
   * over the specified key range, and sets the position of the cursor to the
   * appropriate record, based on the specified direction. If the key range is
   * not specified or is null, then the range includes all the records. If at
   * least one record matches the key range, then a success event is fired on
   * the result object, with its result set to the new IDBCursor object; the
   * value of the cursor object is set to a structured clone of the referenced
   * value. If no records match the key range, then then an error event is fired
   * on the request object, with its code set to NOT_FOUND_ERR and a suitable
   * message.
   * 
   * @param range The key range to use as the cursor's range
   * @param direction The cursor's required direction. See IDBCursor Constants
   *        for possible values
   * @return A request object on which subsequent events related to this
   *         operation are fired
   * @throws IDBDatabaseException
   * @see <a href="http://www.w3.org/TR/IndexedDB/#widl-IDBIndex-openCursor">W3C
   *      IDBIndex-openCursor</a>
   */
  public final IDBRequest openCursor(IDBKeyRange range, int direction)
      throws IDBDatabaseException {
    try {
      return openCursor0(range, direction);
    } catch (JavaScriptException e) {
      throw new IDBDatabaseException(e.getName(), e);
    }
  }

  private final native IDBRequest openCursor0(IDBKeyRange range, int direction) /*-{
		return this.openCursor(range, direction);
  }-*/;

  /**
   * Returns an IDBRequest object, and, in a separate thread, creates a cursor
   * over the specified key range, as arranged by this index, and sets the
   * position of the cursor to the appropriate record, based on the specified
   * direction. If the key range is not specified or is null, then the range
   * includes all the records. If at least one record matches the key range,
   * then a success event is fired on the result object, with its result set to
   * the new IDBCursor object; the value of the cursor object is set to the
   * value of the found record. If no records match the key range, then then an
   * error event is fired on the request object, with its code set to
   * NOT_FOUND_ERR and a suitable message.
   * 
   * @param range The key range to use as the cursor's range
   * @param direction The cursor's required direction. See IDBCursor Constants
   *        for possible values
   * @return A request object on which subsequent events related to this
   *         operation are fired
   * @throws IDBDatabaseException
   * @see <a
   *      href="http://www.w3.org/TR/IndexedDB/#widl-IDBIndex-openKeyCursor">W3C
   *      IDBIndex-openKeyCursor</a>
   */
  public final IDBRequest openKeyCursor(IDBKeyRange range, int direction)
      throws IDBDatabaseException {
    try {
      return openKeyCursor0(range, direction);
    } catch (JavaScriptException e) {
      throw new IDBDatabaseException(e.getName(), e);
    }
  }

  private final native IDBRequest openKeyCursor0(IDBKeyRange range,
      int direction) /*-{
		return this.openKeyCursor(range, direction);
  }-*/;

  /**
   * @param keypath The key path of this index. If null, this index is not
   *        auto-populated.
   * @see <a href="http://www.w3.org/TR/IndexedDB/#widl-IDBIndex-keyPath">W3C
   *      IDBIndex-keyPath</a>
   */
  public final native void setKeyPath(String keyPath) /*-{
		return this.keyPath = keyPath;
  }-*/;

  /**
   * @param name The name of this index
   * @see <a href="http://www.w3.org/TR/IndexedDB/#widl-IDBIndex-name">W3C
   *      IDBIndex-name</a>
   */
  public final native void setName(String name) /*-{
		return this.name = name;
  }-*/;

  /**
   * @param storeName The name of the object store referenced by this index.
   * @see <a
   *      href="http://www.w3.org/TR/IndexedDB/#widl-IDBIndex-objectStore">W3C
   *      IDBIndex-objectStore </a>
   */
  public final native void setStoreName(String storeName) /*-{
		return this.storeName = storeName;
  }-*/;

  /**
   * @param unique If true, this index does not allow duplicate values for a
   *        key.
   * @see <a href="http://www.w3.org/TR/IndexedDB/#widl-IDBIndex-unique">W3C
   *      IDBIndex-unique</a>
   */
  public final native void setUnique(boolean unique) /*-{
		return this.unique = unique;
  }-*/;

}
